def combinations(list, n):
    """Generates all combinations of n elements out of list."""
    l = len(list)
    if n == 0:
        yield []
    else:
        for i in xrange(l):
            for p in combinations(list[:i] + list[i+1:], n - 1):
                yield [list[i]] + p 
                
def selections(list, n):
    """Generates all selections of n elements out of list."""
    l = len(list)
    if n == 0:
        yield []
    else:
        for i in xrange(l):
            for s in selections(list[i+1:], n - 1):
                yield [list[i]] + s

def splits(list):
    """Generates all possible ways to divide a list in two sublists."""
    if list == []:
        yield ([], [])
    else:
        for (left, right) in splits(list[1:]):
            yield ([list[0]] + left, right)
            yield (left, [list[0]] + right)
        
def permutations(list):
    """Generates all permutations of list."""
    l = len(list)
    if l == 0:
        yield []
    else:
        for i in xrange(l):
            for p in permutations(list[:i] + list[i+1:]):
                yield [list[i]] + p

def rotations(list):
    """Generates all rotations of list."""
    for i in xrange(len(list)):
        yield list[i+1:] + list [:i+1]
